﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;
using Afru;

namespace Afru
{
    public class KeyboardManager : Component
    {
       /// <summary>
       /// Manages keyboard input for ease of use
       /// </summary>
        #region Variables

        KeyboardState oldKeyboardState;
        KeyboardState currentKeyboardState;

        /// <summary>
        /// Variables for checking how long things were pressed for.
        /// </summary>
        Dictionary<Keys, float>
            PressLengths,
            ReleasedLength;
        List<Keys> LengthCheckedKeys;
        int i;

        #endregion

        #region Constructor

        public KeyboardManager()
        {
            currentKeyboardState = new KeyboardState();
            oldKeyboardState = new KeyboardState();
            this.Visible = false;

            PressLengths = new Dictionary<Keys, float>();
            ReleasedLength = new Dictionary<Keys, float>();
            LengthCheckedKeys = new List<Keys>();
        }

        #endregion

        #region Class functions

        /// <summary>
        /// Use this to determine if a key is being held
        /// </summary>
        /// <param name="key">The key to check</param>
        /// <returns>Returns true if the key is held.</returns>
        public bool IsKeyHeld(Keys key)
        {
            if (currentKeyboardState.IsKeyDown(key) && oldKeyboardState.IsKeyDown(key))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// Use this to check if a key was just released
        /// </summary>
        /// <param name="key">The key to check</param>
        /// <returns>Returns true if the key was released</returns>
        public bool IsKeyReleased(Keys key)
        {
            if (currentKeyboardState.IsKeyUp(key) && oldKeyboardState.IsKeyDown(key))
            {
                return true;
            }
            else
            {
                return false;
            }

        }

        /// <summary>
        /// Use this to see if the key was being pressed
        /// </summary>
        /// <param name="key">The key to check</param>
        /// <returns>Returns true if the key is pressed</returns>
        public bool IsKeyPressed(Keys key)
        {
            if (currentKeyboardState.IsKeyDown(key) && !oldKeyboardState.IsKeyDown(key))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// Add a key to the list of keys we want to monitor the time pressed for.
        /// </summary>
        /// <param name="key">They key to monitor.</param>
        public void AddKey(Keys key)
        {
            PressLengths.Add(key, 0.0f);
            ReleasedLength.Add(key, 0.0f);
            LengthCheckedKeys.Add(key);
        }

        /// <summary>
        /// Check how long a key was held for so long.
        /// </summary>
        /// <param name="key">The key to check the time held for. Note: AddKey() needs to be called first.</param>
        /// <returns>Time a key was held for, 0f if it wasnt a key that has been added.</returns>
        public float HeldFor(Keys key)
        {
            if (!PressLengths.ContainsKey(key))
            {
                return 0f;
            }
            return PressLengths[key];
        }

        /// <summary>
        /// Check how long a key was held for when released.
        /// </summary>
        /// <param name="key">The key to check the time hald for. Note: AddKey() needs to be called first.</param>
        /// <returns>Time a key was held for, 0f if it wasnt a key that has been added.</returns>
        public float ReleasedTime(Keys key)
        {
            if (!ReleasedLength.ContainsKey(key))
            {
                return 0f;
            }
            return ReleasedLength[key];
        }

        #endregion

        #region Overridden functions

        public override void Update()
        {
 	        oldKeyboardState = currentKeyboardState;
            currentKeyboardState = Keyboard.GetState();

            for (i = 0; i < LengthCheckedKeys.Count; i++)
            {
                if (this.IsKeyHeld(LengthCheckedKeys[i]))
                {
                    PressLengths[LengthCheckedKeys[i]] += ParentEngine.GameTime.ElapsedGameTime.Milliseconds;
                }
                else if (this.IsKeyReleased(LengthCheckedKeys[i]))
                {
                    PressLengths[LengthCheckedKeys[i]] += ParentEngine.GameTime.ElapsedGameTime.Milliseconds;
                    ReleasedLength[LengthCheckedKeys[i]] = PressLengths[LengthCheckedKeys[i]];
                }
                else
                {
                    PressLengths[LengthCheckedKeys[i]] = 0.0f;
                }
            }

            base.Update();
        }

        #endregion

    }
}
